package org.komarichin.jpa.service;

import org.komarichin.jpa.dao.IRoleDAO;
import org.komarichin.jpa.dao.IUserDAO;
import org.komarichin.jpa.entity.IRole;
import org.komarichin.jpa.entity.IUser;
import org.komarichin.jpa.service.exceptions.DublicateUserException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.providers.encoding.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * User: Michael Komarichin
 * Date: 28.09.2009
 * Time: 13:24:39
 */
@Service
public class UserService implements IUserService {

    private static final Logger log = LoggerFactory.getLogger(UserService.class);

    @Autowired
    protected IRoleDAO roleDAO;
    @Autowired
    protected IUserDAO userDAO;
    @Autowired
    private PasswordEncoder passwordEncoder;

    /**
     * {@inheritDoc}
     */
    @Override
    public IRole getRoleById(Long id) {
        IRole role = roleDAO.getRoleById(id);
        log.debug("getRolesByID#id : {}, return: {}", id, role);
        return role;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<IRole> getAllRoles() {
        List<IRole> roles = roleDAO.getAll();
        log.debug("getAllRoles, return:  list of roles : {}",
                roles);
        return roles;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<IRole> getAllowRoles(Long permission) {
        List<IRole> roles = roleDAO.getAllowRoles(permission);
        log.debug("getAllowRoles#permission : {} list of roles : {}",
                permission, roles);
        return roleDAO.getAllowRoles(permission);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void saveRole(IRole object) {
        roleDAO.save(object);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void updateRole(IRole object) {
        roleDAO.update(object);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void saveOrUpdateRole(IRole object) {
        roleDAO.saveOrUpdate(object);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void deleteRole(IRole object) {
        roleDAO.delete(object);
    }


    /**
     * {@inheritDoc}
     */
    @Override
    public IUser getUserById(Long id) {
        IUser user = userDAO.getUserById(id);
        log.debug("getUserByID#id : {}, return: {}", id, user);
        return user;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<IUser> getAllUsers() {
        List<IUser> users = userDAO.getAll();
        log.debug("getAllUsers, return: list of roles : {}",
                users);
        return users;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void saveUser(IUser object) {
        userDAO.save(object);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void updateUser(IUser object) {
        userDAO.update(object);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void saveOrUpdateUser(IUser object) {
        userDAO.saveOrUpdate(object);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void deleteUser(IUser object) {
        userDAO.delete(object);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IUser enroll(String login, String password, String hint) throws DublicateUserException {
        log.debug("enroll#login: {}, password: {}, hint: {}", new Object[]{login, password, hint});
        if (isUserExists(login)) {
            throw new DublicateUserException("user with login: " + login + " exists");
        }
        IRole userRole = roleDAO.getRoleByName(USER_ROLE);
        if (userRole == null) {
            userRole = roleDAO.createRole(USER_ROLE, Long.MAX_VALUE);
        }
        return userDAO.enroll(login, passwordEncoder.encodePassword(password, null), hint, userRole);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IUser login(String login, String password) {
        return userDAO.login(login, passwordEncoder.encodePassword(password, null));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IUser forgot(String login, String hint) {
        return userDAO.forgot(login, hint);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IUser findByName(String login) {
        return userDAO.findByName(login);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isUserExists(String login) {
        return userDAO.isUserExists(login);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public List<IUser> getAllowUsers(Long permission) {
        return userDAO.getAllowUsers(permission);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IRole getRoleByName(String name) {
        return roleDAO.getRoleByName(name);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public IRole createSystemRole(){
        IRole role = getRoleByName(SYSTEM_ROLE);
        if(role == null){
            role = roleDAO.createRole(SYSTEM_ROLE, 0l);
        }
        return role;
    }
}
